<?php
namespace app\common\library;

use GatewayWorker\Lib\Gateway;
use think\facade\Db;
use think\facade\Log;
use app\common\library\OrderExpense;
/**
 * 用于检测业务代码死循环或者长时间阻塞等问题
 * 如果发现业务卡死，可以将下面declare打开（去掉//注释），并执行php start.php reload
 * 然后观察一段时间workerman.log看是否有process_timeout异常
 */
/**
 * 主逻辑
 * 主要是处理 onConnect onMessage onClose 三个方法
 * onConnect 和 onClose 如果不需要可以不用实现并删除
 */
class Events
{
    
    /**
    * 当客户端发来消息时触发
    * @param int $client_id 连接id
    * @param mixed $message 具体消息
    */
    public static function onMessage($client_id, $message)
    {
        $result = '';
        try {
                Db::execute('select 1');
                Log::info('select db');
            } catch (\Throwable $th) {
                Db::close();
            }
        if(strlen($message)==2 && $message =='55' ){
            $result = '55';
            Log::info('heart-client_id:'.$client_id);
            $payload = Db::name('Payload')->where('l',$client_id)->order('id,desc')->value('i');
            if(!empty($payload)){
                Db::name('DeviceEngine')->where('engine_name',$payload)->update(['is_online'=>1,'update_time'=>time()]);
            }
        }else{
            $c = substr($message,10,2);
            $payload = [];
            
            switch ($c) {
                case '6F': //时间同步 heart 心跳 每4秒一次 41000000006F04000DE2B0
                    $len = hexdec(substr($message,12,2)); //长度
                    $payload['c'] = '69';
                    $payload['t'] = time();
                    $payload['ct'] = date('Y-m-d H:i:s');
                    $payload['m'] = substr($message,14,$len*2);//机器号字节码
                    $payload['i'] = $payload['d'] = hexdec($payload['m']);
                    $payload['h'] = $message;
                    $payload['l'] = $client_id;
                    Db::name('Payload')->insert($payload);
                    $m = substr($message,0,12);
                    $d = sprintf('%02X',date('y')).sprintf('%02X',date('m')).sprintf('%02X',date('d')).sprintf('%02X',date('H')).sprintf('%02X',date('i')).sprintf('%02X',date('s'));
                    $result = $m.sprintf('%02X',strlen($d)/2).$d;
                    unset($len,$payload,$m,$d);
                break;
                case '70': //下载参数
                    $len = hexdec(substr($message,12,2)); //长度
                    $payload['c'] = '70';
                    $payload['t'] = time();
                    $payload['ct'] = date('Y-m-d H:i:s');
                    $payload['m'] = substr($message,14,$len*2);//机器号字节码
                    $payload['i'] = $payload['d'] = hexdec($payload['m']);
                    $payload['h'] = $message;
                    $payload['l'] = $client_id;
                    Db::name('Payload')->insert($payload);
                    $engine = Db::name('DeviceEngine')->where('engine_name',$payload['i'])->find();//查找主板配置
                    if(empty($engine)){
                        $engineconfig = Db::name('EngineConfig')->where('id',1)->find();
                        unset($engineconfig['id']);
                        $engineconfig['engine_hex_name'] = $payload['m'];
                        $engineconfig['engine_name'] = $payload['i'];
                        $engineconfig['create_time'] = time();
                        $engineconfig['update_time'] = time();
                        Db::name('DeviceEngine')->insert($engineconfig);
                    }else{
                        $engineconfig =$engine;
                    }
                    $m = substr($message,0,12);
                    $d ='';
                    for ($i=0; $i <32 ; $i++) { 
                        $d.=sprintf('%04X',$engineconfig['p'.($i+1)]);
                    }
                    $result =$m.sprintf('%02X',64).$d;
                    unset($len,$payload,$engine,$engineconfig,$m,$d);
                break;
                case '71': //上传状态
                    $len = hexdec(substr($message,12,2)); //长度
                    $payload['c'] = '71';
                    $payload['t'] = time();
                    $payload['ct'] = date('Y-m-d H:i:s');
                    $payload['m'] = substr($message,14,8);//机器号字节码
                    $payload['i'] = hexdec($payload['m']);
                    $payload['d'] = substr($message,14,$len*2);
                    $payload['h'] = $message;
                    $payload['l'] = $client_id;
                    Db::name('Payload')->insert($payload);
                    $m = substr($message,0,12);
                    $d ='00';
                    $result =$m.'01'.$d;
                    unset($len,$payload,$engine,$m,$d);
                    break;
                case '72': //账户验证 ID+Miami(主机主动发送)
                //心跳41时间00 00 00命令00 72数量0E从机编号910000 00 0D	E2 B0 4字节用户序号	00 00 00 E9类型01状态01 4字节账户金额00 00 45 0A (最后两位角分)
                    break;
                case '73': //账户验证 IC卡
                    $len = hexdec(substr($message,12,2)); //长度
                    $payload['c'] = '73';
                    $payload['t'] = time();
                    $payload['ct'] = date('Y-m-d H:i:s');
                    $payload['m'] = substr($message,14,8);//机器号字节码
                    $payload['i'] = hexdec($payload['m']);
                    $payload['d'] = substr($message,14,$len*2);
                    $payload['u'] = hexdec(substr($message,22,8));//卡号
                    $payload['h'] = $message;
                    $payload['l'] = $client_id;
                    Db::name('Payload')->insert($payload);
                    $m = substr($message,0,12);
                    $error=1;
                    if(!empty($payload['u'])){//卡号有信息
                        $account = Db::name('Account')->where('account_card',$payload['u'])->field('id,account_card,balance,extra_amount')->find();
                        if(!empty($account)){ //查找到账户;
                            //$account = Db::name('Account')->alias('a')->join('__USER__ u','u.account_id = a.id')->where('a.account_card',$payload['u'])->field('a.id,a.account_card,a.balance,a.extra_amount,u.level_id')->find();
                            $user = Db::name('User')->where('account_id',$account['id'])->field('u.openid,u.id,u.level_id')->find();
                            if(isset($user['level_id']) && $user['level_id']>0){ //会员属性
                                $error=0;
                                $result = $m.'0E'.sprintf('%08X',$payload['i']).sprintf('%08X',$account['id']).'0101'.sprintf('%06X',300).'00';
                            }else{
                                $amount = $account['balance']+$account['extra_amount'];
                                if($amount>10){ //余额大于最低消费
                                    $amountArr = explode('.',(string)$amount);
                                    $error=0;
                                    $result = $m.'0E'.sprintf('%08X',$payload['i']).sprintf('%08X',$account['id']).'0101'.sprintf('%06X',$amountArr[0]).sprintf('%02X',$amountArr[1]);
                                    unset($amountArr);
                                }
                                unset($amount);
                            }
                            unset($user);
                        }
                        unset($account);
                    }
                    if($error == 1){
                        $result = $m.'0A'.sprintf('%08X',$payload['i']).'FFFFFFFF0105';
                    }
                    unset($len,$payload,$error,$m);
                    break;
                case '74': //账户验证 手机+密码
                    break;
                case '75': //预结算
                    $len = hexdec(substr($message,12,2)); //长度
                    $payload['c'] = '75';
                    $payload['t'] = time();
                    $payload['ct'] = date('Y-m-d H:i:s');
                    $payload['m'] = substr($message,14,8);//机器号字节码
                    $payload['i'] = hexdec($payload['m']);
                    $payload['d'] = substr($message,14,$len*2);
                    $payload['u'] = hexdec(substr($message,22,8));//account_id;
                    $payload['y'] = hexdec(substr($message,30,6));//元
                    $payload['j'] = hexdec(substr($message,36,2));//角分
                    $payload['h'] = $message;
                    $payload['l'] = $client_id;
                    Db::name('Payload')->insert($payload);
                    $m = substr($message,0,12);
                    $error=1;
                    if(!empty($payload['u'])){//消费信息
                        $amount = OrderExpense::prepaied($payload['u'],$payload['y'],$payload['j']);
                        if($amount > 0){
                            $error = 0;
                            $result = $m.'0C'.sprintf('%08X',$payload['i']).sprintf('%08X',$payload['u']).sprintf('%06X',$amount).'00';
                            if($amount === true){
                                $result = $m.'0C'.sprintf('%08X',$payload['i']).sprintf('%08X',$payload['u']).sprintf('%06X',$payload['y']).sprintf('%02X',$payload['j']);
                            }
                        }else{
                            $error = 1;
                        }
                    }
                    if($error == 1){
                        $result = $m.'0C'.sprintf('%08X',$payload['i']).sprintf('%08X',$payload['u']).sprintf('%06X',$payload['y']).sprintf('%02X',$payload['j']);
                    }
                    unset($len,$payload,$error,$m);
                    break;
                case '76': //结算
                    $len = hexdec(substr($message,12,2)); //长度
                    $payload['c'] = '76';
                    $payload['t'] = time();
                    $payload['ct'] = date('Y-m-d H:i:s');
                    $payload['m'] = substr($message,14,8);//机器号字节码
                    $payload['i'] = hexdec($payload['m']);
                    $payload['d'] = substr($message,14,$len*2);
                    $payload['u'] = hexdec(substr($message,22,8));//卡号
                    $payload['y'] = hexdec(substr($message,30,6));//元
                    $payload['j'] = hexdec(substr($message,36,2));//角分
                    $payload['h'] = $message;
                    $payload['l'] = $client_id;
                    Db::name('Payload')->insert($payload);
                    $m = substr($message,0,12);
                    $error=1;
                    if(!empty($payload['u'])){//账户有信息settlement
                        $amount = OrderExpense::settlement($payload['u'],$payload['y'],$payload['j']);
                        if($amount > 0){
                            $error = 0;
                            $result = $m.'0C'.sprintf('%08X',$payload['i']).sprintf('%08X',$payload['u']).sprintf('%06X',$amount).'00';
                            if($amount === true){
                                $result = $m.'0C'.sprintf('%08X',$payload['i']).sprintf('%08X',$payload['u']).sprintf('%06X',$payload['y']).sprintf('%02X',$payload['j']);
                            }
                        }else{
                            $error = 1;
                        }
                        
                    }
                    if($error == 1){
                        $result = $m.'0C'.sprintf('%08X',$payload['i']).sprintf('%08X',$payload['u']).sprintf('%06X',$payload['y']).sprintf('%02X',$payload['j']);
                    }
                    unset($len,$payload,$error,$m);
                break;
                case '78': //主机发送命令
                    //11结算
                break;
                default:
                    $payload['c'] = '0';
                    $payload['t'] = time();
                    $payload['ct'] = date('Y-m-d H:i:s');
                    $payload['m'] = substr($message,14,8);//机器号字节码
                    $payload['d'] = '';
                    $payload['h'] = $message;
                    $payload['l'] = $client_id;
                    Db::name('Payload')->insert($payload);
                    unset($c,$payload,$message,$result);
                    return '00';
                    break;
            }
            unset($c,$payload,$message);
        }
        Gateway::sendToClient($client_id, $result);
    }

}